package com.hcloud.auth.api.config;

import com.hcloud.auth.api.token.MyJwtAccessTokenConverter;
import com.hcloud.auth.api.user.HcloudUserDetails;
import com.hcloud.common.core.constants.AuthConstants;
import com.hcloud.system.core.bean.user.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import java.util.HashMap;
import java.util.Map;

/**
 * @Auther hepangui
 * @Date 2018/12/6
 */
@Configuration
public class TokenConfig {

    @Configuration
    @ConditionalOnProperty(name = "hcloud.oauth.token.type", havingValue = "jwt",matchIfMissing = true)
    public class JwtTokenStoreConfig {

        @Bean
        @Primary
        public TokenStore tokenStore() {
            return new JwtTokenStore(jwtAccessTokenConverter());
        }

        /**
         * 此处使用简单的对称加密，如果需要非对称加密可参考上述文章
         *
         * @return
         */
        @Bean
        @Primary
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter jwtAccessTokenConverter = new MyJwtAccessTokenConverter();
            jwtAccessTokenConverter.setSigningKey(AuthConstants.JWT_SIGNKEY);
            return jwtAccessTokenConverter;
        }

    }


    @Configuration
    @ConditionalOnProperty(name = "hcloud.oauth.token.type", havingValue = "redis")
    public class RedisTokenStoreConfig {

        @Autowired(required = false)
        private RedisConnectionFactory redisConnectionFactory;

        @Bean
        public TokenStore tokenStore() {
            RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
            tokenStore.setPrefix(AuthConstants.OAUTH_TOKEN_PERDIX);
            return tokenStore;
        }


        /**
         * @return
         */
        @Bean
        @Primary
        public TokenEnhancer tokenEnhancer() {
            return (accessToken, authentication) -> {
                HcloudUserDetails user = (HcloudUserDetails) authentication.getUserAuthentication().getPrincipal();
                final Map<String, Object> additionalInfo = new HashMap<>();
                User user1 = new User();
                BeanUtils.copyProperties(user.getBaseUser(), user1);
                user1.setPassword("");
                user1.setRole("");
                additionalInfo.put(AuthConstants.USER, user1);
                ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
                return accessToken;
            };
        }
    }
}
